package com.supermarket.api.service.impl;

import com.supermarket.api.bean.order.*;
import com.supermarket.api.common.exception.BaseException;
import com.supermarket.api.common.filters.UserCacheManage;
import com.supermarket.api.common.redis.RedisConstants;
import com.supermarket.api.common.redis.RedisOperate;
import com.supermarket.api.common.utils.DateUtil;
import com.supermarket.api.entity.*;
import com.supermarket.api.enums.OrderPayType;
import com.supermarket.api.enums.OrderStatusType;
import com.supermarket.api.repository.*;
import com.supermarket.api.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单服务层
 * @author 李其伟
 * @date 2023/11/11
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService{

    @Autowired
    private RedisOperate redisOperate;

    @Autowired
    private OrderRecordRepository orderRecordRepository;
    @Autowired
    private OrderItemRepository orderItemRepository;
    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private ProductSkuRepository productSkuRepository;
    @Autowired
    private ProductResRepository productResRepository;
    @Autowired
    private CartRepository cartRepository;

    @Override
    public List<ProductItem> confirmOrder(ConfirmOrderReq req) {
        Long userId = UserCacheManage.getUserIdCache();
        List<String> skuCodes = req.getSkuCodes();

        //商品条目
        List<ProductItem> productItemList = new ArrayList<>();
        for(String skuCode : skuCodes){
            ProductItem productItem = buildProductItem(skuCode);

            //查询购物车
            CartEntity cartEntity = cartRepository.findAllByUserIdAndSkuCode(userId,skuCode);
            if(cartEntity == null){
                productItem.setNumber(1);
            }else {
                productItem.setNumber(cartEntity.getNumber());
            }

            productItemList.add(productItem);
        }

        return productItemList;
    }

    /**
     * 构建商品细则
     * @param skuCode
     * @return
     */
    private ProductItem buildProductItem(String skuCode){
        ProductItem productItem = new ProductItem();

        ProductSkuEntity productSkuEntity = productSkuRepository.findAllBySkuCode(skuCode);
        String sku = productSkuEntity.getSku();
        ProductEntity productEntity = productRepository.findAllBySku(sku);

        productItem.setSku(productSkuEntity.getSku());
        productItem.setSkuCode(productSkuEntity.getSkuCode());
        productItem.setShopId(productEntity.getShopId());
        productItem.setTitle(productEntity.getTitle());
        productItem.setSubTitle(productEntity.getSubTitle());

        if(productSkuEntity.getPic()==null){
            productItem.setPic(productEntity.getPic());
        }else {
            productItem.setPic(productSkuEntity.getPic());
        }
        if(productSkuEntity.getPrice()==null){
            productItem.setPrice(productEntity.getPrice());
        }else {
            productItem.setPrice(productSkuEntity.getPrice());
        }

        productItem.setSpData(productSkuEntity.getSpData());

        return productItem;
    }

    @Transactional(rollbackFor = BaseException.class)
    @Override
    public String generateOrder(GenerateOrderReq req) {
        Long userId = UserCacheManage.getUserIdCache();
        Date date = new Date();

        OrderRecordEntity recordEntity = new OrderRecordEntity();
        List<OrderItemEntity> orderItemEntityList = new ArrayList<>();

        //订单号
        String orderSn = generateOrderSn(date);
        recordEntity.setOrderSn(orderSn);

        //商品细则列表
        for(ProductItem item : req.getProductItemList()){
            OrderItemEntity orderItemEntity = new OrderItemEntity();

            String skuCode = item.getSkuCode();
            ProductItem productItem = buildProductItem(skuCode);
            BeanUtils.copyProperties(productItem,orderItemEntity);

            orderItemEntity.setNumber(item.getNumber());
            orderItemEntity.setOrderSn(orderSn);
            orderItemEntity.setOrderNote(item.getOrderNote());

            orderItemEntityList.add(orderItemEntity);
        }

        //计算总金额
        recordEntity.setTotalAmount(handleTotalAmount(orderItemEntityList));
        orderItemRepository.saveAll(orderItemEntityList);

        recordEntity.setStatus(OrderStatusType.OBLIGATION.getCode());
        recordEntity.setPayType(OrderPayType.NONE.getCode());
        recordEntity.setDeleteStatus(0);
        recordEntity.setUserId(userId);
        recordEntity.setCreateTime(date);
        orderRecordRepository.save(recordEntity);

        //删除购物车
        deleteCartItemList(orderItemEntityList,userId);

        return orderSn;
    }


    /**
     * 生成23位订单编号:17位日期+6位以上自增id
     */
    private String generateOrderSn(Date date) {
        StringBuilder sb = new StringBuilder();

        String dateStr = DateUtil.parseDateToStr(date,DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        sb.append(dateStr);

        String key = RedisConstants.ORDER_SN + dateStr;
        Long increment = redisOperate.incr(key, 1);
        String incrementStr = increment.toString();
        if (incrementStr.length() <= 6) {
            sb.append(String.format("%06d", increment));
        } else {
            sb.append(incrementStr);
        }

        return sb.toString();
    }

    /**
     * 计算总金额
     * @param orderItemList
     * @return
     */
    private BigDecimal handleTotalAmount(List<OrderItemEntity> orderItemList) {
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItemEntity orderItem : orderItemList) {
            BigDecimal oneAmount = orderItem.getPrice().multiply(new BigDecimal(orderItem.getNumber()));
            totalAmount = totalAmount.add(oneAmount);
        }
        return totalAmount;
    }


    /**
     * 删除下单商品的购物车信息
     */
    private void deleteCartItemList(List<OrderItemEntity> orderItemEntityList,Long userId) {
        List<String> skuCodes = orderItemEntityList.stream().map(OrderItemEntity::getSkuCode).collect(Collectors.toList());

        List<CartEntity> list = new ArrayList<>();
        List<CartEntity> cartEntityList = cartRepository.findAllByUserIdOrderByUpdateTimeDesc(userId);

        for (CartEntity entity : cartEntityList) {
            if(skuCodes.contains(entity.getSkuCode())){
                list.add(entity);
            }
        }
        cartRepository.deleteInBatch(list);
    }

    @Override
    public Page<OrderRes> list(OrderReq req) {
        Long userId = UserCacheManage.getUserIdCache();
        List<Integer> statusList = OrderStatusType.getAllStatus();

        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        /**
         * 当前页， 每页记录数， 排序方式
         */
        Pageable pageable = PageRequest.of(req.getPageNum() , req.getPageSize(), sort);

        Page<OrderRecordEntity> page = null;
        if(statusList.contains(req.getStatus())){
            page = orderRecordRepository.findAllByUserIdAndStatusAndDeleteStatusOrderByCreateTimeDesc(userId,req.getStatus(),0,pageable);
        }else {
            page = orderRecordRepository.findAllByUserIdAndDeleteStatusOrderByCreateTimeDesc(userId,0,pageable);
        }
        List<OrderRecordEntity> list = page.getContent();

        //获取商品细则
        List<String> orderSnList = list.stream().map(OrderRecordEntity::getOrderSn).collect(Collectors.toList());
        List<OrderItemEntity>  orderItemEntityList = orderItemRepository.findAllByOrderSnIn(orderSnList);

        //设置列表
        List<OrderRes> resList = new ArrayList<>();
        for(OrderRecordEntity recordEntity : list){
            OrderRes orderRes = new OrderRes();
            BeanUtils.copyProperties(recordEntity,orderRes);

            String orderSn = recordEntity.getOrderSn();
            List<OrderItemEntity> chooseEntityList = new ArrayList<>();
            for(OrderItemEntity itemEntity: orderItemEntityList){
                if(orderSn.equals(itemEntity.getOrderSn())){
                    chooseEntityList.add(itemEntity);
                }
            }
            orderRes.setOrderItemEntityList(chooseEntityList);
            resList.add(orderRes);
        }
        //重新创建
        return new PageImpl<>(resList,page.getPageable(),page.getTotalElements());
    }

    @Transactional(rollbackFor = BaseException.class)
    @Override
    public void paySuccess(PaySuccessReq req) {
        //设置订单记录
        OrderRecordEntity orderRecordEntity = getOrderRecordEntity(req.getOrderSn());
        orderRecordEntity.setStatus(OrderStatusType.COMPLETE.getCode());
        orderRecordEntity.setPayType(req.getPayType());
        orderRecordEntity.setPayTime(new Date());
        orderRecordRepository.save(orderRecordEntity);

        //查询订单细则
        String orderSn = orderRecordEntity.getOrderSn();
        List<String> orderSnList = new ArrayList<>();
        orderSnList.add(orderSn);
        List<OrderItemEntity> orderItemEntityList = orderItemRepository.findAllByOrderSnIn(orderSnList);

        for(OrderItemEntity entity : orderItemEntityList){
            //查询商品规格
            String skuCode = entity.getSkuCode();
            ProductSkuEntity productSkuEntity = productSkuRepository.findAllBySkuCode(skuCode);
            //查询资源信息
            String resUuid = productSkuEntity.getResUuid();
            ProductResEntity productResEntity = productResRepository.findAllByUuid(resUuid);

            //设置话术
            String speak = productResEntity.getSpeak();
            speak = speak.replace("{{下载地址}}",productResEntity.getFile());
            speak = speak.replace("{{解压密码}}",productResEntity.getPassword());
            entity.setSpeak(speak);

            //保存订单细则
            orderItemRepository.save(entity);
        }
    }

    @Override
    public void cancelOrder(String orderSn) {
        OrderRecordEntity entity = getOrderRecordEntity(orderSn);
        entity.setStatus(OrderStatusType.CLOSE.getCode());
        orderRecordRepository.save(entity);
    }

    @Override
    public OrderRes detail(String orderSn) {
        OrderRecordEntity entity = getOrderRecordEntity(orderSn);
        OrderRes res = new OrderRes();
        BeanUtils.copyProperties(entity,res);
        List<OrderItemEntity> orderItemEntityList = orderItemRepository.findAllByOrderSnIn(new ArrayList<String>(Collections.singletonList(entity.getOrderSn())));
        res.setOrderItemEntityList(orderItemEntityList);
        return res;
    }

    @Override
    public void deleteOrder(String orderSn) {
        OrderRecordEntity entity = getOrderRecordEntity(orderSn);
        entity.setDeleteStatus(1);
        orderRecordRepository.save(entity);
    }


    private OrderRecordEntity getOrderRecordEntity(String orderSn){
        Long userId = UserCacheManage.getUserIdCache();
        OrderRecordEntity entity = orderRecordRepository.findAllByOrderSnAndUserId(orderSn,userId);
        Assert.notNull(entity,orderSn+" 订单号找不到");
        return entity;
    }
}

























